package com.internetCafes.spms.common.module.ueditor.util;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.Map.Entry;

/**
 * 
 * @Description: [ Request工具类 ]
 *
 * @author 踩坑填坑
 * @Email: 120987555@qq.com
 * @Date: 2017年7月1日 下午4:21:21
 * 
 * @Version: V1.0
 */
public class RequestUtils {

	/**
	 * @描述: 获取HttpServletRequest对象(在没有传递request时获取)<br/>
	 *
	 * @return HttpServletRequest
	 */
	public static HttpServletRequest getHttpServletRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	/**
	 * @描述: 获取HttpSession对象(在没有传递request时获取)<br/>
	 * 
	 *
	 * @return HttpSession
	 */
	public static HttpSession getHession() {
		return getHttpServletRequest().getSession();
	}

	/**
	 * @描述: 获取请求的上下文(在没有传递request时获取)<br/>
	 *      (Scheme + "://" + ServerName + ":" + ServerPort + ContextPath)
	 *
	 * @return (Scheme + "://" + ServerName + ":" + ServerPort + ContextPath)
	 */
	public static String getCtx() {
		return getCtx(getHttpServletRequest());
	}

	/**
	 * @描述: 获取请求的上下文<br/>
	 *      (Scheme + "://" + ServerName + ":" + ServerPort + ContextPath)
	 *
	 * @param request
	 * @return (Scheme + "://" + ServerName + ":" + ServerPort + ContextPath)
	 */
	public static String getCtx(HttpServletRequest request) {
		String ctx = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
				+ request.getContextPath();
		return ctx;
	}

	/**
	 * @描述: 获取请求发出的IP地址(已处理代理IP的情况)
	 *
	 * @param request
	 * @return 请求的客户端IP地址
	 */
	public static String getRequestIp() {
		return getRequestIp(getHttpServletRequest());
	}

	/**
	 * @描述: 获取请求发出的IP地址(已处理代理IP的情况)
	 *
	 * @param request
	 * @return 请求的客户端IP地址
	 */
	public static String getRequestIp(HttpServletRequest request) {

		String ipAddress = request.getHeader("x-forwarded-for");

		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}

		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}

		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}

		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
															// = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}

		return ipAddress;
	}

	/**
	 * @描述: 判断请求是否来自移动设备端
	 *
	 * @return
	 */
	public static boolean isFromMobile() {
		return isFromMobile(getHttpServletRequest());
	}

	/**
	 * @描述: 判断请求是否来自移动设备端
	 *
	 * @author: 傅国彬
	 * @date: 2017年7月27日 下午4:34:04
	 *
	 * @param request
	 * @return
	 */
	public static boolean isFromMobile(HttpServletRequest request) {
		String[] agents = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };
		String ua = request.getHeader("User-Agent");
		boolean flag = false;

		// 排除Windows操作系统
		if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) {

			// 排除 苹果桌面系统
			if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) {

				for (String item : agents) {

					if (ua.contains(item)) {
						flag = true;
						break;
					}

				}

			}
		}

		return flag;
	}

	/**
	 * 
	 * @描述: 是否为微信端发出的请求
	 *
	 * @param request
	 * @return 是微信:true; 不是微信:false
	 */
	public static boolean isFromWeixin() {
		return isFromMobile(getHttpServletRequest());
	}

	/**
	 * 
	 * @描述: 是否为微信端发出的请求
	 *
	 * @author: 傅国彬
	 * @date: 2017年7月10日 上午9:22:14
	 *
	 * @param request
	 * @return 是微信:true; 不是微信:false
	 */
	public static boolean isFromWeixin(HttpServletRequest request) {
		String userAgent = request.getHeader("user-agent");
		return userAgent != null && userAgent.indexOf("MicroMessenger") > 0;
	}

	/**
	 * @描述: request请求数据转Map
	 *
	 * @param request
	 * @return Map<String, String>格式数据
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> request2Map(HttpServletRequest request) throws Exception {
		// 解析结果存储在HashMap
		Map<String, String> map = new HashMap<String, String>();

		InputStream inputStream = request.getInputStream();
		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		List<Element> elementList = root.elements();

		// 遍历所有子节点
		for (Element e : elementList) {
			map.put(e.getName(), e.getText());
		}

		inputStream.close();
		inputStream = null;

		return map;
	}

	/**
	 * @描述: request请求数据转Map
	 *
	 * @param request
	 * @return XML标准格式数据
	 */
	public static String request2Xml(HttpServletRequest request) {

		StringBuffer sb = new StringBuffer();
		try {
			InputStream inputStream = request.getInputStream();
			InputStreamReader streamReader = new InputStreamReader(inputStream);
			BufferedReader br = new BufferedReader(streamReader);
			String str = null;
			while ((str = br.readLine()) != null) {
				sb.append(str);
			}
			inputStream.close();
			streamReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * @描述: 获取Request所有参数为Map<String,String>格式
	 *
	 * @param request
	 * @return 值为字符串格式的Map数据
	 */
	public static Map<String, String> getAllParameters4StringMap(HttpServletRequest request) {
		Map<String, String> returnMap = new HashMap<String, String>();
		Map<String, String[]> parameters = request.getParameterMap();// 把请求参数封装到Map<String,String[]>中
		String name = "";
		String value = "";
		for (Entry<String, String[]> entry : parameters.entrySet()) {
			name = entry.getKey();
			String[] values = entry.getValue();
			if (values == null) {
				value = "";
			} else if (values.length > 1) {
				for (int index = 0; index < values.length; index++) {
					value = values[index] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = values[0];// 唯一值的情况
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	/**
	 * @描述: 获取Request所有参数为Map<String,String>格式(排除值null或者""空字符串数据)
	 *
	 * @param request
	 * @return 值为字符串格式的Map数据
	 */
	public static Map<String, String> getAllParameters4StringMapWithoutNull(HttpServletRequest request) {
		Map<String, String> returnMap = new HashMap<String, String>();
		Enumeration<?> temp = request.getParameterNames();
		if (null != temp) {
			while (temp.hasMoreElements()) {
				String en = (String) temp.nextElement();
				String value = request.getParameter(en);
				returnMap.put(en, value);
				// 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
				// System.out.println("ServletUtil类247行 temp数据的键=="+en+"
				// 值==="+value);
				if (null == returnMap.get(en) || "".equals(returnMap.get(en))) {
					returnMap.remove(en);
				}
			}
		}
		return returnMap;
	}

	/**
	 * @描述: 获取Request所有参数为Map<String,Object>格式
	 *
	 * @param request
	 * @return 值为Object格式的Map数据
	 */
	public static Map<String, Object> getAllParameters4ObjectMap(HttpServletRequest request) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Map<String, String[]> parameters = request.getParameterMap();// 把请求参数封装到Map<String,String[]>中

		Iterator<Entry<String, String[]>> iterator = parameters.entrySet().iterator();
		String name = "";
		String value = "";

		while (iterator.hasNext()) {
			Entry<String, String[]> entry = iterator.next();
			name = entry.getKey();
			Object valueObj = entry.getValue();

			if (valueObj == null) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int index = 0; index < values.length; index++) {
					value = values[index] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	/**
	 * @描述: 获取全路径(不包括参数)
	 *
	 * @return
	 */
	public static String getFullPathWithParams(HttpServletRequest request) {
		return getFullPathWithOutParams(request) + "?" + getQueryParams(request);
	}

	/**
	 * @描述: 获取全路径(不包括参数)
	 *
	 * @author: 傅国彬
	 * @date: 2017年7月25日 上午10:56:22
	 *
	 * @param request
	 * @return
	 */
	public static String getFullPathWithOutParams(HttpServletRequest request) {
		StringBuilder sb = new StringBuilder();
		sb.append(getScheme(request));// 协议
		sb.append("://" + getServerName(request));// 域名
		sb.append(":" + getServerPort(request));// 端口号
		String contextPath = getContextPath(request);
		if (contextPath != null && contextPath.length() > 1) {
			sb.append("/" + contextPath);// 工程名称
		}
		return sb.toString();
	}

	/**
	 * @描述: 获取协议类型(如:http/https/ftp/svn)
	 *
	 * @param request
	 * @return
	 */
	public static String getScheme(HttpServletRequest request) {
		return request.getScheme();
	}

	/**
	 * @描述: 获取域名
	 *
	 * @author: 傅国彬
	 * @date: 2017年7月25日 上午10:43:18
	 *
	 * @param request
	 * @return
	 */
	public static String getServerName(HttpServletRequest request) {
		return request.getServerName();
	}

	/**
	 * @描述: 获取端口号
	 *
	 * @param request
	 * @return
	 */
	public static int getServerPort(HttpServletRequest request) {
		return request.getServerPort();
	}

	/**
	 * @描述: 获取项目名称
	 *
	 * @return
	 */
	public static String getContextPath(HttpServletRequest request) {
		return request.getContextPath();
	}

	/**
	 * @描述: 获取请求的参数
	 *
	 * @param request
	 * @return
	 */
	public static String getQueryParams(HttpServletRequest request) {
		return request.getQueryString();
	}

}
